package com.system.template.core;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.StringWriter;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xhtmlrenderer.pdf.ITextFontResolver;
import org.xhtmlrenderer.pdf.ITextRenderer;

import com.itextpdf.text.pdf.BaseFont;
import com.system.template.TemplateHandler;
import com.system.template.core.pdf.ITextRenderer2;
import com.system.template.core.pdf.PdfPagingSealUtil;
import com.system.template.core.pdf.PdfWatermark;
import com.system.template.core.pdf.PdfBuilder;
import com.system.template.utils.FileUtil;

import freemarker.template.Configuration;
import freemarker.template.Template;

public class PdfTemplate extends TemplateCore {
	
	private static final Logger LOGGER = LoggerFactory.getLogger(PdfTemplate.class);
	private static Configuration configuration = null;

	/** 
	 * 根据模板生成相应的文件
	 * @param map 			保存数据的map
	 * @param templatePath 	模板文件的地址
	 * @param createPath	 生成的文档输出地址
	 * @return
	 */
	public synchronized File process(Map<?, ?> map, String template, String path) {
		if (map == null) {
			throw new RuntimeException("数据不能为空");
		}
		if (template == null) {
			throw new RuntimeException("模板文件不能为空");
		}
		if (path == null) {
			throw new RuntimeException("输出路径不能为空");
		}
		int templatePathIndex = template.lastIndexOf("/");
		if(templatePathIndex == -1) {
			templatePathIndex = template.lastIndexOf(File.separator);
		}
		String templatePath = template.substring(0, templatePathIndex);
		FileUtil.createDir(templatePath);
		String templateName = template.substring(templatePathIndex + 1, template.length());
		if (configuration == null) {
			//这里Configurantion对象不能有两个，否则多线程访问会报错
			configuration = new Configuration(Configuration.VERSION_2_3_23);
			configuration.setDefaultEncoding("utf-8");
			configuration.setClassicCompatible(true);
		}
		try {
			configuration.setDirectoryForTemplateLoading(new File(templatePath));
		} catch (Exception e) {
			configuration.setClassForTemplateLoading(TemplateHandler.class, templatePath);
		}
		
		int pathIndex = path.lastIndexOf("/");
		if(pathIndex == -1) {
			pathIndex = path.lastIndexOf(File.separator);
		}
		String pathDir = path.substring(0, pathIndex);
		FileUtil.createDir(pathDir);
		File file = null;
		try {
			Template t = configuration.getTemplate(templateName);
			StringWriter stringWriter = new StringWriter();
			//这里w是一个输出地址，可以输出到任何位置，如控制台，网页等
			t.process(map, stringWriter);
			
			//生成pdf
			file = parsePdf(stringWriter.toString(), path);
			stringWriter.close();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return file;
	}

	/**
	 * HTML代码转PDF文档
	 * 
	 * @param content 待转换的HTML代码
	 * @param storagePath 保存为PDF文件的路径
	 */
	private File parsePdf(String content, String path) {
		FileOutputStream os = null;
		try {
			File file = new File(path);
			if(!file.exists()) {
				file.createNewFile();
			}
			os = new FileOutputStream(file);

			ITextRenderer2 renderer = new ITextRenderer2(new ITextRenderer());
		    
			//解决中文支持问题[模版内必须指定<body style="font-family:'Arial Unicode MS'">]
			ITextFontResolver resolver = renderer.getFontResolver();
			resolver.addFont("/font/ARIALUNI.TTF", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
			renderer.setDocumentFromString(content);
			//解决图片的相对路径问题,图片路径必须以file开头
			//renderer.getSharedContext().setBaseURL("file:/");
			PdfWatermark pdfWatermark = this.getPdfWatermark();
			renderer.setPdfPageEvent(new PdfBuilder(pdfWatermark));
			renderer.layout();
			renderer.createPDF(os);
			if (pdfWatermark != null && pdfWatermark.getType().intValue() == 1) {
				String newName = "new_" + file.getName();
				String newPath = path.replace(file.getName(), newName);
				PdfPagingSealUtil.stamperCheckMarkPDF(path, newPath, pdfWatermark);
				FileUtil.moveFile(newPath, path);
				return new File(path);
			}
			return file;
		} catch (Exception e) {
			LOGGER.error(e.getMessage(), e);
			e.printStackTrace();
		}finally {
			if(null != os) {
				try {
					os.close();
				} catch (IOException e) {
					LOGGER.error(e.getMessage(), e);
				}
			}
		}
		return null;
	}

	@Override
	public String readContent(Map<?, ?> map, String template) {
		if (map == null) {
			throw new RuntimeException("数据不能为空");
		}
		if (template == null) {
			throw new RuntimeException("模板文件不能为空");
		}
		int templatePathIndex = template.lastIndexOf("/");
		if(templatePathIndex == -1) {
			templatePathIndex = template.lastIndexOf(File.separator);
		}
		String templatePath = template.substring(0, templatePathIndex);
		FileUtil.createDir(templatePath);
		String templateName = template.substring(templatePathIndex + 1, template.length());
		if (configuration == null) {
			//这里Configurantion对象不能有两个，否则多线程访问会报错
			configuration = new Configuration(Configuration.VERSION_2_3_23);
			configuration.setDefaultEncoding("utf-8");
			configuration.setClassicCompatible(true);
		}
		try {
			configuration.setDirectoryForTemplateLoading(new File(templatePath));
		} catch (Exception e) {
			configuration.setClassForTemplateLoading(TemplateHandler.class, templatePath);
		}
		StringWriter stringWriter = null;
		try {
			Template t = configuration.getTemplate(templateName);
	        stringWriter = new StringWriter();
			//这里w是一个输出地址，可以输出到任何位置，如控制台，网页等
			t.process(map, stringWriter);
			return stringWriter.toString();  
		} catch (Exception e) {
			throw new RuntimeException(e);
		} finally {
			if (stringWriter != null) {
				try {
					stringWriter.close();
				} catch (IOException e) {
				}
			}
		}
	}
	
	/*public static void main(String[] args) {
		String storagePath = "D://pdf.pdf";
		StringBuffer content = new StringBuffer();
		content.append("<a href=\"https://www.baidu.com\">link btn</a>");
		PdfTemplate pdf = new PdfTemplate();
		boolean bool = pdf.parsePdf(content.toString(), storagePath);
		System.out.println("bool: " + bool);
	}*/

}
